#ifndef __MV_AUTO360_MOSAIC_H__
#define __MV_AUTO360_MOSAIC_H__

#ifndef __cplusplus
#  error core.hpp header must be compiled as C++
#endif

#include <opencv2/opencv.hpp>

using namespace cv;

// 摄像头参数
class CameraCfg {

public:
	int findCBBlkSize; 	// 查找棋盘时自适应阈值块大小
	int findCBOffset; 		// 查找棋盘自适应阈值偏移值

	//显示相关参数
	Size2f cameraImgSize;		// 相机图像大小

	float sizePerPix;  		// 非透视下每点对应实际物理尺寸（cm）

	Point2f dispStart;		// 显示在拼合图中起如位置cm）
	Size2f dispSize;		// 显示在拼合图中大小cm）
	float dispRotate;		// 旋转x角度显示在拼合图中

	float cbTopWidth;		// 显示的校准布上边宽度（cm）
	float cbDownWidth;		// 显示的校准布下边宽度（cm）
	float cbHeight;   		// 显示的校准布高度（cm）
	Point2f cbDownEdgeCenterPos;		// 校准布低边中心位置cm）

public:
	CameraCfg() {
		findCBBlkSize = 31;
		findCBOffset = 1;

		cameraImgSize = Size(720, 576);
		sizePerPix = 2;

		dispStart = Point2f(0, 0);
		dispSize = Size(1, 1);
		dispRotate = 0.0;

		cbDownEdgeCenterPos = Point2f(0, 0);		// 摄像头低边中心位置
		cbTopWidth = 160.0;
		cbDownWidth = 160.0;
		cbHeight = 120.0;
	}
};

class Auto360Mosaic {

private:

private:
	// 根据标记点生成前后左右４幅图片的采样点
	int makeCameraMapPoints(CameraCfg &camCfg, InputArray markPts, OutputArray mapPoints);

public:
	CameraCfg camCfg[4];

	float frontOffset;		// 前面校准布与左右校准布的竖直距离（cm）
	Size2f carSize;			// 车长（cm）
	Size2f dispMaxPix;		// 显示最大像素

	Mat mark[4];				// 校准标记点

	Mat mapPts[4];				// 每个摄像头生成的小图座标映射
	Mat camImg[4];

	float frontTransition;	// 前图与左右图过度高度(pix)
	float backTransition;		// 后图与左右图过度高度(pix)
	Mat transImg[8]; 		// 4摄像头8个过渡图像
	Mat transMask[8];

	Mat imgMap;

public:
	int makeCamerasMap(void);
//	int getCameraCalData(Mat &srcImg, CameraCfg &camCfg);

	// 参数初始化
	void initPara(CameraCfg &camCfg);

	// 处理镜头校准测试
	void proCalcTest(Mat &srcImg);

	// 查找标记点
	int findChessBoard(Mat &srcImg, CameraCfg camCfg, OutputArray markPts);

	// 生成过渡区掩模
	int makeTransMask(Size size, OutputArray mask);
	// 生成过渡区图像
	void makeTransArea(Mat &img, Mat &mask, OutputArray outImg);

	// 生成拼接好的映射点
	int makeSpliceImg(Mat inImg[], OutputArray outPts);

	// 按座标点生成图像
	void makeImgWithMapPoints(Mat &srcImg, Mat &pt, Mat &dstImg);

public:

	Auto360Mosaic() {
		frontOffset = 120;				// cm
		carSize = Size(200, 450);		// cm
		dispMaxPix = Size(280, 460);	// pix

		frontTransition = 36;			// (pix)
		backTransition = 36;
	}

	// 获取最大显示尺寸（cm）
	Size2f getMaxDispSize(float sizePerPix) {
		Size2f size(dispMaxPix.width * sizePerPix, dispMaxPix.height * sizePerPix);
		return size;
	}
};

#endif
